/*
 * @Description: "回顾链表"
 * @Author: Han_ruofei
 * @Date: 2022-07-06
 * @LastEditTime: 2022-07-06
 * @LastEditors: Please set LastEditors
 */

/**
 * @func  nodeList
 * @desc 节点
 * @param {data}  
 * @return {nodeList} 
 */
class NodeList {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}
class LinkedList {
    constructor() {
        this.length = 0;
        this.head = null;
    }
    // 追加节点
    appendNode(val) {
        // 先创建一个新节点，判断是否有头节点，如果没有则设置为头节点
        // 如果有的话则找到最后一个节点并添加
        let newNode = new NodeList(val)
        if (!this.head) {
            this.head = newNode;
        } else {
            let cur = this.head;
            // 找到最后的节点
            while (cur.next) {
                cur = cur.next;
            }
            cur.next = newNode
        }
        this.length++;

    }
    nodeToString() {
        let cur = this.head;
        let listStr = '';
        while (cur) {
            listStr += cur.data + ' '
            cur = cur.next
        }
        return listStr
    }
    // 指定位置插入节点
    insertNode(val, position) {
        // 1.先判断是否超出边界
        if (position > this.length || position < 0) return false;
        let newNode = new NodeList(val)
        // position为0则表明将当前节点作为头节点
        if (position === 0) {
            newNode.next = this.head;
            this.head = newNode
        } else {
            // 找到position的前一个节点
            let previous = this.getNodeByposition(position - 1)
            previous.next = newNode.next;
            previous.next = newNode
        }
        this.length++
        return true
    }
    // 删除指定位置的节点，并返回被删除的元素的值
    removeAt(position) {
        // 先判断index是否在范围内
        if (position >= this.length || position < 0) return false;
        // 同样还要区分是否删除头节点
        let current = this.head
        let cur = this.getNodeByposition(position)

        if (position === 0) {
            this.head = current.next;
        } else {
            let previous = this.getNodeByposition(position - 1)
            previous.next = previous.next.next;
        }
        this.length--;
        return cur
    }
    // 删除通过值删除链表元素
    removeElement(val) {
        let position = this.getPostionByData(val);
        console.log(position);
        let previous = this.getNodeByposition(position - 1);
        console.log(previous);
        let tempNode = previous.next;
        if (position > -1) {
            previous.next = previous.next.next
            return tempNode
        }
        // 说明没有找到
        else {
            return false
        }

    }
    // 查找对应元素的索引
    getPostionByData(item) {
        let currentNode = this.head;
        let index = 0
        while (currentNode) {
            if (currentNode.data === item) {
                return index
            }
            currentNode = currentNode.next;
            index++;
        }
        // 没有找到就返回-1
        return -1
    }
    // 清空链表
    clearNode() {
        this.head = null;
        this.length = 0;
    }
    // 将指定位置的值进行替换
    updataNode(position, newVal) {
        if (position < -1 || position > this.length) return false;
        // 先找到指定位置的节点
        let cur = this.getNodeByposition(position);
        // 返回-1则说明没有找到
        if (cur) {
            cur.data = newVal
            return true;
        } else {
            return false;
        }


    }

    // 获取链表中对应索引的元素
    getNodeByposition(position) {
        // 先判断传入的position是否正常
        if (position < 0 || position > this.length) {
            return -1
        }
        let current = this.head;
        while (position--) {
            current = current.next
        }
        return current
    }
    // 获取指定索引的值
    getDataByPosition(position) {
        if (position < 0 || position > this.length) {
            return false
        }
        let current = this.head;
        while (position--) {
            current = current.next
        }
        return current.data;
    }

}
let list = new LinkedList();
list.appendNode('apple1')
list.appendNode('banana2')
list.appendNode('orange3')
list.appendNode('peach4')
// list.insertNode('apple3', 2)
// console.log(list.nodeToString())
// console.log('node is ', list.getNodeByposition(1));
// console.log('data is ', list.getPostionByData('orange3'));
// list.clearNode()
// console.log(list.updataNode(1, 'purple'));
// console.log(list.removeElement('orange3'));
console.log(list.removeAt(1));
console.log(list.nodeToString());
// console.log(list.nodeToString(), list.length);